ЛЕКЦИЯ 2

Основы программирования.

Введение в Pascal. Типы данных. Операции.

 

Алфавит языка Pascal

 

Любой естественный язык состоит из таких элементов, как символы, слова, словосочетания, предложения. В языке программирования также есть аналогичные элементы: символы, слова, выражения (словосочетания), операторы (предложения).

 

Слова образуются из совокупности символов. Выражения - это группы слов, а операторы - это комбинации слов и выражений. Символы языка - есть элементарные знаки (буквы), которые используются для составления каких-то текстов. Так вот, набор этих символов и образует алфавит языка.

 

 Алфавит языка Pascal состоит из:

 1.прописных и  строчных  букв  латинского  алфавита, в который  входят следующие символы:

- A B C D E F G H I J K L M N O P Q R S T U V W X Y Z - прописные буквы;

- a b c d e f g h i j k l m n o p q r s t u v w x y z - строчные буквы;

2. десятичные арабские цифры: 0 1 2 3 4 5 6 7 8 9;

3. шестнадцатеричные цифры (строятся из десятичных цифр и букв от A до F);

4. 32 прописные и строчные буквы русского алфавита;

5. специальные  символы:

 

+ плюс

– минус

* звездочка

/ дробь

= равно

> больше

< меньше

[ ] квадратные скобки

( ) круглые скобки

@ коммерческое а

{ } фигурные скобки

. точка

, запятая

: двоеточие

‘ апостроф

; точка с запятой

# номер

$ денежная единица

^ тильда

  пробел не обознач.

 

Комбинации специальных  символов  могут  образовывать  составные  символы:

: = присваивание ;

< > не равно;

>= больше или равно;

<= меньше или равно;

.. диапазон значений ;

(*  *)  или { }- комментарий.

 

Структура Pascal-программы

 

Для того чтобы Pasсal-компилятор правильно понял, какие именно действия от него ожидаются, ваша программа должна быть оформлена в полном соответствии с синтаксисом (правилами построения программ) этого языка.

 

Любая Pascal-программа может состоять из следующих блоков (квадратными скобками здесь и далее помечены необязательные части):

 

   program <имя_программы>;

   [ uses <имена_подключаемых_модулей>;]               

   [ label <список_меток>;]     

   [ const <имя_константы> = <значение_константы>;]

   [ type <имя_типа> = <определение_типа>;]    

   [ var <имя_переменной> : <тип_переменной>;]       

   [ procedure <имя_процедуры> <описание_процедуры>;]

   [ function <имя_функции> <описание_функции>;]

   begin   {начало основного тела программы}

   <операторы>

   end.  (* конец основного тела программы *)

 

Поздние версии компиляторов языка Pascal уже не требуют указывать название программы, то есть строку program <имя_программы>; можно опустить. Но это возможно только в том случае, если вся программа содержится в одном модуле-файле. Если же программа состоит из нескольких самостоятельных кусков - модулей, то каждый из них должен иметь заголовок (program или unit).

 

Любой из перечисленных необязательных разделов может встречаться в тексте программы более одного раза, их общая последовательность также может меняться, но при этом всегда должно выполняться главное правило языка Pascal: прежде чем объект будет использован, он должен быть объявлен и описан.

 

Компиляторы языка Pascal не различают строчные и прописные буквы, а пробельные символы игнорируют, поэтому текст программы можно структурировать так, чтобы читать и отлаживать его было наиболее удобно.

 

Директивы компилятора

 

Строка, начинающаяся символами {$, является не комментарием, а директивой компилятора - специальной командой, от которой зависит процесс компиляции и выполнения программы. Директивы мы будем рассматривать в тех разделах, к которым они относятся "по смыслу".

 

Например, строка {$I-,Q+} отключает контроль правильности ввода-вывода, но включает контроль переполнения при вычислениях.

 

Идентификаторы

 

Имена, даваемые программным объектам (константам, типам, переменным, функциям и процедурам, да и всей программе целиком) называются идентификаторами. Они могут состоять только из цифр, латинских букв и знака "_" (подчеркивание). Однако цифра не может начинать имя. Идентификаторы могут иметь любую длину, но если у двух имен первые 63 символа совпадают, то такие имена считаются идентичными.

 

Вы можете давать программным объектам любые имена, но необходимо, чтобы они отличались от зарезервированных слов, используемых языком Pascal, потому что компилятор все равно не примет переменные с "чужими" именами.

 

Приведем список наиболее часто встречающихся зарезервированных слов:

 

and               goto                       set

array            implementation      shl

begin           in                           shr

case              interface                 string

const            label                       then

div               mod                       text             

do                nil                          to

downto        not                         type

else              of                           unit

end               or                           until  

file               pointer                   uses

far                procedure               var

for                program                 while

forward        record                    with

function       repeat                     xor

 

Переменные и типы данных

 

Переменная - это программный объект, значение которого может изменяться в процессе работы программы.

 

Тип данных - это характеристика диапазона значений, которые могут принимать переменные, относящиеся к этому типу данных.

 

Все используемые в программе переменные должны быть описаны в специальном разделе var по следующему шаблону:

 

var     <имя_переменной_1> [, <имя_переменной_2, _>] : <имя_типа_1>;

          <имя_переменной_3> [, <имя_переменной_4, _>] : <имя_типа_2>;

 

Язык Pascal обладает большим набором разнообразных типов данных, однако сейчас мы укажем лишь некоторые из них. Обо всех же типах данных мы поговорим далее.

 

Константы

 

Константа - это объект, значение которого известно еще до начала работы программы.

 

Константы необходимы для оформления наглядных программ, незаменимы при использовании в тексте программы многократно повторяемых значений, удобны в случае необходимости изменения этих значений сразу во всей программе.

 

В языке Pascal существует три вида констант:

- неименованные константы (цифры и числа, символы и строки, множества);

- именованные нетипизированные константы;

- именованные типизированные константы.

 

Неименованные константы

 

Неименованные константы не имеют имен, и потому их не нужно описывать.

 

Тип неименованной константы определяется автоматически, по умолчанию:

- любая последовательность цифр (возможно, предваряемая знаком "-" или "+" или разбиваемая одной точкой) воспринимается компилятором как неименованная константа - число (целое или вещественное);

- любая последовательность символов, заключенная в апострофы, воспринимается как неименованная константа - строка;

- любая последовательность целых чисел либо символов через запятую, обрамленная квадратными скобками, воспринимается как неименованная константа - множество.

 

Кроме того, существуют две специальные константы true и false, относящиеся к логическому типу данных.

 

Примерами использования неименованных констант могут послужить следующие операторы:

 

int1 := -10;

real2 := 12.075 + х;

char3 := 'z';

string4 := 'abc' + string44;

set5 := [1,3,5] * set55;

boolean6 := true;

 

Нетипизированные константы

 

Именованные константы, как следует из их названия, должны иметь имя. Стало быть, эти имена необходимо сообщить компилятору, то есть описать в специальном разделе const.

 

Если не указывать тип константы, то по ее внешнему виду компилятор сам определит, к какому (базовому) типу ее отнести. Любую уже описанную константу можно использовать при объявлении других констант, переменных и типов данных. Вот несколько примеров описания нетипизированных именованных констант:

 

const

                    n = -10;

                    m = 1000000000;

                    mmm = n*100;

                    x = 2.5;

                    c = 'z';

                    s = 'string';

                    b = true;

 

Типизированные константы

 

Типизированные именованные константы представляют собой переменные(!) с начальным значением, которое к моменту старта программы уже известно. Следовательно, во-первых, типизированные константы нельзя использовать для определения других констант, типов данных и переменных, а во-вторых, их значения можно изменять в процессе работы программы.

 

Описание типизированных констант производится по следующему шаблону:

 

const <имя_константы> : <тип_константы> = <начальное_значение>;

 

Из приведенных ниже примеров видно, как это сделать:

 

const

n: integer = -10;

                    x: real = 2.5;

                    c: char = 'z';

                    b: boolean = true;

 

Примеры типизированных констант других типов мы будем приводить по мере изучения соответствующих типов данных.

 

Типы данных языка Pascal

 

Компиляторы языка Pascal требуют, чтобы сведения об объеме памяти, необходимой для работы программы, были предоставлены до начала ее работы. Для этого в разделе описания переменных (var) нужно перечислить все переменные, используемые в программе. Кроме того, необходимо также сообщить компилятору, сколько памяти каждая из этих переменных будет занимать.

 

Все это можно сообщить программе, просто указав тип будущей переменной. Имея информацию о типе переменной, компилятор "понимает", сколько байт необходимо отвести под нее, какие действия с ней можно производить и в каких конструкциях она может участвовать.

Для удобства программистов в языке Pascal существует множество стандартных типов данных и плюс к тому возможность создавать новые типы данных на основе уже имеющихся (стандартных или опять-таки определенных самим программистом), которые называются конструируемые.

 

Разделение на базовые и конструируемые типы данных в языке Pascal показано в таблице:

 

 

 

Порядковые(дискретные) типы данных

 

Адресные типы данных

Структурированные типы данных

 

Арифметические типы данных

Базовые типы данных

Логический

boolean

Символьный

char

Целые

shortint

byte

integer

word

longint

Вещественные

real

single

double

extended

comp

 

Нетипизи

рованный указатель

pointer

 

Конструируемые типы

Перечисляемый

week = (su, mo, tu, we, th, fr,sa);

Типизированный указатель

^<тип>

Массив array

Строка string

Запись record

Файл

text

file

Процедурный

Объектный

Интервал (диапазон)

budni = mo..fr;

Типы данных, конструируемые программистом

 

                       

Порядковые типы данных

 

Среди базовых типов данных особо выделяются порядковые типы. Такое название можно обосновать двояко:

1. Каждому элементу порядкового типа может быть сопоставлен уникальный (порядковый) номер. Нумерация значений начинается с нуля. Исключение - типы данных shortint, integer и longint. Их нумерация совпадает со значениями элементов.

2.Кроме того, на элементах любого порядкового типа определен порядок (в математическом смысле этого слова), который напрямую зависит от нумерации. Таким образом, для любых двух элементов порядкового типа можно точно сказать, который из них меньше, а который - больше.

 

Стандартные подпрограммы, обрабатывающие порядковые типы данных

 

Только для величин порядковых типов определены следующие функции и процедуры:

1.Функция ord(x) возвращает порядковый номер значения переменной x (относительно того типа, к которому принадлежит переменная х).

2.Функция pred(x) возвращает значение, предшествующее х (к первому элементу типа неприменима).

3.Функция succ(x) возвращает значение, следующее за х (к последнему элементу типа неприменима).

4.Процедура inc(x) возвращает значение, следующее за х (для арифметических типов данных это эквивалентно оператору x:=x+1).

5.Процедура inc(x,k) возвращает k-е значение, следующее за х (для арифметических типов данных это эквивалентно оператору x:=x+k).

6.Процедура dec(x) возвращает значение, предшествующее х (для арифметических типов данных это эквивалентно оператору x:=x-1).

7.Процедура dec(x,k) возвращает k-e значение, предшествующее х (для арифметических типов данных это эквивалентно оператору x:=x-k).

 

На первый взгляд кажется, будто результат применения процедуры inc(x) полностью совпадает с результатом применения функции succ(x). Однако разница между ними проявляется на границах допустимого диапазона. Функция succ(x) неприменима к максимальному элементу типа, а вот процедура inc(x) не выдаст никакой ошибки, но, действуя по правилам машинного сложения, прибавит очередную единицу к номеру элемента. Номер, конечно же, выйдет за пределы диапазона и за счет усечения превратится в номер минимального значения диапазона. Получается, что процедуры inc() и dec() воспринимают любой порядковый тип словно бы "замкнутым в кольцо": сразу после последнего вновь идет первое значение.

 

Поясним все сказанное на примере. Для типа данных

type sixteen = 0..15;

 

попытка прибавить 1 к числу 15 приведет к следующему результату:

 

+         1        1        1        1

                                      1

1        0        0        0        0

 

Начальная единица будет отсечена, и потому получится, что inc(15)=0.

 

Аналогичная ситуация на нижней границе допустимого диапазона произвольного порядкового типа данных наблюдается для процедуры dec(x) и функции pred(x):

 

dec(min_element)= max_element

 

Типы данных, относящиеся к порядковым

 

1. Логический тип boolean имеет два значения: false и true, и для них выполняются следующие равенства:

 

ord(false)=0, ord(true)=1, false<true,

pred(true)=false, succ(false)=true,

inc(true)=false, inc(false)=true,

dec(true)=false, dec(false)=true.

 

2. В символьный тип char входит 256 символов расширенной таблицы ASCII (например, 'a', 'b', 'я', '7', '#'). Номер символа, возвращаемый функцией ord(), совпадает с номером этого символа в таблице ASCII.

 

3. Целочисленные типы данных сведем в таблицу:

 

Тип данных

Количество байтов

Диапазон

shortint

1

-128..127

byte

1

0..255

integer

2

-32768..32767

word

2

0..65535

longint

4

-2147483648..2147483647

 

4. Перечисляемые типы данных задаются в разделе type явным перечислением их элементов. Например:

 

type

week =(sun,mon,tue,wed,thu,fri,sat)

                                    0     1     2     3     4    5   6

 

Напомним, что для этого типа данных:

 

inc(sat) = sun, dec(sun) = sat.

 

5. Интервальные типы данных задаются только границами своего диапазона. Например:

 

Type

 month = 1..12;

          budni = mon..fri;

 

6. Типы данных, конструируемые программистом, описываются в разделе type по следующему шаблону:

 

type <имя_типа> = <описание_типа>;

 

Например:

 

type lat_bukvy = 'a'..'z','A'..'Z';

 

Базовые типы данных являются стандартными, поэтому нет нужды описывать их в разделе type. Однако при желании это тоже можно сделать, например, дав длинным определениям короткие имена. Скажем, введя новый тип данных

 

type int = integer;

 

можно немного сократить текст программы.

 

Вещественные типы данных

 

Напомним, что эти типы данных являются арифметическими, но не порядковыми.

 

Тип данных

Количество байтов

Диапазон (абсолютной величины)

single

4

1.5*10-45..3.4*1038

real

6

2.9*10-39..1.7*1038

double

8

5.0*10-324..1.7*10308

extended

10

3.4*10-4932..1.1*104932

comp

8

-263+1..263-1

 

Конструируемые типы данных

 

Эти типы данных (вместе с определенными для них операциями) мы будем рассматривать далее на протяжении нескольких лекций.

 

Операции и выражения

 

Арифметические операции

 

Поговорим об операциях - стандартных действиях, разрешенных для переменных того или иного базового типа данных. Основу будут составлять арифметические и логические операции.

 

Замечание: Все перечисленные ниже операции (за исключением унарных '-' и not) требуют двух операндов.

 

1. Логические операции (and – логическое И, or – логическое ИЛИ, not – логическое НЕ, xor – исключающее ИЛИ) применимы только к значениям типа boolean. Их результатом также служат величины типа boolean. Приведем таблицы значений для этих операций:

 

not

and

true  false  or

true  false  xor

true  false

true

false

false true

true  false

true  false  true

false false false

true  true  true

true  false false

false true

true  false

 

2. Операции сравнения (=, <>, >, <, <=, >=) применимы ко всем базовым типам. Их результатами также являются значения типа boolean.

 

3. Операции целочисленной арифметики применимы только к целым типам. Их результат - целое число, тип которого зависит от типов операндов.

 

a div b - деление а на b нацело (не нужно, наверное, напоминать, что деление на 0 запрещено, поэтому в таких случаях операция выдает ошибку). Результат будет принадлежать к типу данных, общему для тех типов, к которым принадлежат операнды.

Например, (shortint div byte = integer). Пояснить это можно так: integer - это минимальный тип, подмножествами которого являются одновременно и byte, и shortint.

 

a mod b - взятие остатка при делении а на b нацело. Тип результата, как и в предыдущем случае, определяется типами операндов, а 0 является запрещенным значением для b. В отличие от математической операции mod, результатом которой всегда является неотрицательное число, знак результата "программистской" операции mod определяется знаком ее первого операнда. Таким образом, если в математике (-2 mod 5)=3, то у нас (-2 mod 5)= -2.

 

a shl k - сдвиг значения а на k битов влево (это эквивалентно умножению значения переменной а на 2k). Результат операции будет иметь тот же тип, что и первый ее операнд (а).

 

a shr k - сдвиг значения а на k битов вправо (это эквивалентно делению значения переменной а на 2k нацело). Результат операции будет иметь тот же тип, что и первый ее операнд (а).

 

and,or,not,xor - операции двоичной арифметики, работающие с битами двоичного представления целых чисел, по тем же правилам, что и соответствующие им логические операции.

 

4. Операции общей арифметики (+, -, *, /) применимы ко всем арифметическим типам. Их результат принадлежит к типу данных, общему для обоих операндов (исключение составляет только операция дробного деления /, результат которой всегда относится к вещественному типу данных).

 

Другие операции

 

Существуют и другие операции, специфичные для значений некоторых стандартных типов данных языка Pascal. Эти операции мы рассмотрим в соответствующих разделах:

#, in, +, *, [] :        см. лекцию 5 «Символы. Строки. Множества»

@, ^             :         см. лекцию 7 «Адреса и указатели»

                                       

Стандартные арифметические функции

 

К арифметическим операциям примыкают и стандартные арифметические функции. Их список с кратким описанием мы приводим в таблице.

                             

Функция

Описание

Тип аргумента

Тип результата

abs(x)

Абсолютное значение (модуль) числа

Арифметический

Совпадает с типом аргумента

arctan(x)

Арктангенс (в радианах)

Арифметический

Вещественный

cos(x)

Косинус (в радианах)

Арифметический

Вещественный

exp(x)

Экспонента (ex)

Арифметический

Вещественный

frac(x)

Взятие дробной части числа

Арифметический

Вещественный

int(x)

Взятие целой части числа

Арифметический

Вещественный

ln(x)

Натуральный логарифм (по основанию e)

Арифметический

Вещественный

odd(x)

Проверка нечетности числа

Целый

boolean

pi

Значение числа

-

Вещественный

round(x)

Округление к ближайшему целому

Арифметический

Целый

trunc(x)

Округление "вниз" - к ближайшему меньшему целому

Арифметический

Целый

sin(x)

Синус (в радианах)

Арифметический

Вещественный

sqr(x)

Возведение в квадрат

Арифметический

Вещественный

sqrt(x)

Извлечение квадратного корня

Арифметический

Вещественный

 

 

Арифметические выражения

 

Все арифметические операции можно сочетать друг с другом - конечно, с учетом допустимых для их операндов типов данных.

 

В роли операндов любой операции могут выступать переменные, константы, вызовы функций или выражения, построенные на основе других операций. Все вместе и называется выражением.

 

Примеры арифметических выражений:

 

(x<0) and (y>0) - выражение, результат которого принадлежит к типу boolean;

 

z shl abs(k) - вторым операндом является вызов стандартной функции;

 

(x mod k) + min(a,b) + trunc(z) - сочетание арифметических операций и вызовов функций;

 

odd(round(x/abs(x))) - "многоэтажное" выражение.

 

Порядок вычислений

 

Если в выражении расставлены скобки, то вычисления производятся в порядке: чем меньше глубина вложенности скобок, тем позже вычисляется заключенная в них операция. Если же скобок нет, то сначала вычисляются значения операций с более высоким приоритетом, затем - с менее высоким. Несколько подряд идущих операций одного приоритета вычисляются в последовательности "слева направо".

 

Таблица 2.1. Приоритеты (для всех) операций языка Pascal 

 

 

Операции

Приоритет

Унарные операции

+, -, not, @, ^, #

Первый(высший)

Операции, эквивалентные умножению

*, /, div, mod, and, shl, shr

Второй

Операции, эквивалентные сложению

+,-, or, xor

Третий

Операции сравнения

=, <>, >, <, <=, >=, in

Четвертый

         

Замечание: Вызов любой функции имеет более высокий приоритет, чем все внешние относительно этого вызова операции. Выражения, являющиеся аргументами вызываемой функции, вычисляются в момент вызова (см. лекцию 6 «Процедуры и функции»).

 

Примеры выражений (с указанием последовательности вычислений) для целых чисел:

 

a + b * c / d         (результат принадлежит к вещественному типу данных);

   3    1   2                      

 

a * not b or c * d = 0 (результат принадлежит к логическому типу данных);

  2   1      4     3    5          

 

-min(a + b, 0) * (a + 1)    (результат принадлежит к целочисленному типу).

3 2       1         5     4                  

 

Преобразование типов данных

 

При выполнении операций компилятору требуется, чтобы типы операндов совпадали: нельзя, например, сложить массив и множество, нельзя передать вещественное число функции, ожидающей целый аргумент, и т.п.

 

Тип результата арифметических операций (а следовательно, и выражений) может отличаться от типов исходных операндов. Например, при "дробном" делении ( / ) одного целого числа на другое целое в ответе получается вещественное. Такое изменение типа данных называется неявным приведением типов.

 

В Pascal преобразование типов следует использовать явно. Исключение сделано только в отношении констант и переменных целого типа, которые разрешается использовать в выражениях вещественного типа.

 

var

x : integer;

y: real;

 

То оператор y:=x+2; будет синтаксически правильным.

В то же время оператор x:=2.0 будет неверным, т.к. преобразование вещественного типа в целый запрещено.  

 

Для преобразования данных в языке предусмотрены стандартные функции, которые получают в качестве параметра значение одного типа а возвращают результат в виде значения другого типа.

Для преобразования вещественного типа в целый имеются две функции – round, которая округляет вещественное до ближайшего целого и trunc, усекает вещественное путем отбрасывания дробной части.

Для преобразования символьного типа в целое число предназначена функция ord, обратное преобразование осуществляет функция chr.

А также функция val, которая преобразует строку в целый и вещественный типы.

 

 

Дополнительно

 

Совместимость типов данных

 

В общем случае при выполнении арифметических (и любых других) операций компилятору требуется, чтобы типы операндов совпадали: нельзя, например, сложить массив и множество, нельзя передать вещественное число функции, ожидающей целый аргумент, и т.п.

 

В то же время, любая процедура или функция, написанная в расчете на вещественные значения, сможет работать и с целыми числами.

 

Правила, по которым различные типы данных считаются взаимозаменяемыми, мы приводим ниже.

 

Эквивалентность

 

Эквивалентность - это наиболее высокий уровень соответствия типов. Она требуется при действиях с указателями (см. лекцию 7 «Адреса и указатели»), а также при вызовах подпрограмм для параметров-переменных (см. лекцию 6 «Процедуры и функции»).

 

Итак, два типа - Т1 и Т2 - будут эквивалентными, если верен хотя бы один вариант из перечисленных ниже:

 

·      Т1 и Т2 совпадают;

·      Т1 и Т2 определены в одном объявлении типа;

·      Т1 эквивалентен некоторому типу Т3, который эквивалентен типу Т2.

 

Поясним это на примере:

 

type T2 = T1;

      T3 = T1;

      T4,T5 = T2;

 

Здесь эквивалентными будут Т1 и Т2; Т1 и Т3; Т1 и Т4; Т1 и Т5; Т4 и Т5. А вот Т2 и Т3 - не эквивалентны.

 

Совместимость

 

Совместимость типов требуется при конструировании выражений, а также при вызовах подпрограмм (для параметров-значений). Совместимость означает, что для переменных этих типов возможна операция присваивания - хотя во время этой операции присваиваемое значение может измениться: произойдет неявное приведение типов данных ("Приведение типов данных" ниже).

 

Два типа Т1 и Т2 будут совместимыми, если верен хотя бы один вариант из перечисленных ниже:

 

·      Т1 и Т2 эквивалентны (в том числе совпадают);

·      Т1 и Т2 - оба целочисленные или оба вещественные;

·      Т1 и Т2 являются подмножествами одного типа;

·      Т1 является некоторым подмножеством Т2;

·      Т1 - строка, а Т2 - символ                                                         (см. лекцию 5 «Символы. Строки. Множества»);

·      Т1 - это тип pointer, а Т2 - типизированный указатель           (см. лекцию 7 «Адреса и указатели»);

·      Т1 и Т2 - оба процедурные, с одинаковым количеством попарно эквивалентных параметров, а для функций - с эквивалентными типами результатов (см. лекцию 6 «Процедуры и функции»).

 

Совместимость по присваиванию

 

В отличие от простой совместимости, совместимость по присваиванию гарантирует, что в тех случаях, когда производится какое-либо присваивание (используется запись вида a:=b; или происходит передача значений в подпрограмму или из нее и т.п.), не произойдет никаких изменений присваиваемого значения.

 

Два типа данных Т1 и Т2 называются совместимыми по присваиванию, если выполняется хотя бы один вариант из перечисленных ниже:

 

·      Т1 и Т2 эквивалентны, но не файлы;

·      Т1 и Т2 совместимы, причем Т2 - некоторое подмножество в Т1;

·      Т1 - вещественный тип, а Т2 - целый.

 

Приведение типов данных

 

Неявное приведение типов данных

 

Как мы говорили тип результата арифметических операций (а следовательно, и выражений) может отличаться от типов исходных операндов. Например, при "дробном" делении ( / ) одного целого числа на другое целое в ответе все равно получается вещественное. Такое изменение типа данных называется неявным приведением типов.

 

Если в некоторой операции присваивания участвуют два типа данных совместимых, но не совместимых по присваиванию, то тип присваиваемого выражения автоматически заменяется на подходящий. Это тоже неявное приведение. Причем в этих случаях могут возникать изменения значений. Скажем, если выполнить такую последовательность операторов

 

a:= 10;                             {a: byte}

a:= -a;

writeln(a);

 

то на экране мы увидим не -10, а 246 (246 = 256 - 10).

 

Неявным образом осуществляется и приведение при несоответствии типов переменной-счетчика и границ в циклах for (см. лекцию 3 «Ввод/вывод. Операторы»).

 

Неявное приведение типов данных можно отключить, если указать директиву компилятора {$R+}, которая принуждает компилятор всегда проверять границы и диапазоны. Если эта директива включена, то во всех ситуациях, в которых по умолчанию достаточно совместимости типов данных, будет необходима их эквивалентность.

 

По умолчанию такая проверка отключена, поэтому во всем дальнейшем изложении (если, конечно, явно не оговорено противное) мы будем считать, что эта директива находится в выключенном состоянии {$R-}.

 

Явное приведение типов данных

 

Тип значения можно изменить и явным способом: просто указав новый тип выражения, например:

 

a:= byte(b)

 

В этом случае переменной а будет присвоено значение, полученное новой интерпретацией значения переменной b. Скажем, если b имеет тип shortint и значение -23, то в a запишется 233 (= 256 - 23).

 

Приводить явным образом можно и типы, различающиеся по длине. Тогда значение может измениться в соответствии с новым типом. Скажем, если преобразовать тип longint в тип integer, то возможны потери из-за отсечения первых двух байтов исходного числа. Например, результатом попытки преобразовать число 100 000 к типу integer станет число 31 072, а к типу word - число 34 464.

 

Функции, изменяющие тип данных

 

Приведем список стандартных функций, аргумент и результат которых принадлежат к совершенно различным типам данных:

 

trunc: real -> integer;

round: real -> integer;

val: string -> byte/integer/real;

chr: byte -> char;

ord: <порядковый_тип> -> longint;